class Vue {
  constructor(options) {
    this.$options = options;
    this.$el = document.querySelector(options.el);
    this.$data = options.data;
    this.$methods = options.methods || {};

    // 将data数据转换为响应式
    this._observe(this.$data);

    // 将methods绑定到this上下文
    this._bindMethods();

    // 编译模板
    this._compile(this.$el);
  }

  _observe(data) {
    const self = this;
    Object.keys(data).forEach(key => {
      let value = data[key];
      
      // 为每个属性创建一个依赖收集器
      const dep = new Dep();
      
      Object.defineProperty(data, key, {
        get() {
          // 如果有Watcher，就将其添加到依赖中
          if (Dep.target) {
            dep.addSub(Dep.target);
          }
          return value;
        },
        set(newValue) {
          if (value !== newValue) {
            value = newValue;
            // 通知所有依赖更新
            dep.notify();
          }
        }
      });

      // 将data属性代理到Vue实例上
      Object.defineProperty(this, key, {
        get() {
          return this.$data[key];
        },
        set(newValue) {
          this.$data[key] = newValue;
        }
      });
    });
  }

  _bindMethods() {
    const self = this;
    Object.keys(this.$methods).forEach(key => {
      self[key] = this.$methods[key].bind(self);
    });
  }

  _compile(el) {
    const childNodes = el.childNodes;
    Array.from(childNodes).forEach(node => {
      // 处理文本节点
      if (node.nodeType === 3) {
        const text = node.textContent;
        const reg = /\{\{(.*?)\}\}/g;
        
        if (reg.test(text)) {
          const key = RegExp.$1.trim();
          // 创建Watcher实例
          new Watcher(this, key, (newValue) => {
            node.textContent = text.replace(reg, newValue);
          });
          
          // 初始渲染数据
          node.textContent = text.replace(reg, this.$data[key]);
        }
      } 
      // 递归处理子节点
      else if (node.nodeType === 1) {
        this._compile(node);
      }
    });
  }
}

// 依赖收集器
class Dep {
  constructor() {
    this.subs = [];
  }
  
  addSub(sub) {
    this.subs.push(sub);
  }
  
  notify() {
    this.subs.forEach(sub => {
      sub.update();
    });
  }
}

// 观察者
class Watcher {
  constructor(vm, key, callback) {
    this.vm = vm;
    this.key = key;
    this.callback = callback;
    
    // 把watcher对象记录到Dep类的静态属性target
    Dep.target = this;
    // 触发getter，进行依赖收集
    this.oldValue = vm[key];
    // 清除标记
    Dep.target = null;
  }
  
  update() {
    const newValue = this.vm[this.key];
    if (this.oldValue !== newValue) {
      this.callback(newValue);
      this.oldValue = newValue;
    }
  }
}